//
//  MujiVideoPlayerView.m
//  ECCoreLibrary
//
//  Created by Samuel Chow on 8/12/13.
//  Copyright (c) 2013 EnglishCentral, Inc. All rights reserved.
//

#import "MujiVideoPlayerView.h"
//#import "ECCoreLibraryDefines.h"

#pragma mark -
#pragma mark Constants

static void *kMujiVideoPlayerViewContext = &kMujiVideoPlayerViewContext;

@interface MujiVideoPlayerView ()

@property (readwrite, nonatomic, weak) AVPlayerLayer *playerLayer;
@property (readwrite, nonatomic, assign, getter = isPlaying) BOOL playing;

@end


@implementation MujiVideoPlayerView

#pragma mark -
#pragma mark Synthesize Properties

@synthesize player        = _player;
@synthesize playerLayer   = _playerLayer;
@synthesize videoFillMode = _videoFillMode;
@synthesize delegate      = _delegate;


#pragma mark -
#pragma mark Getters

- (BOOL)isReadyForVisualDisplay
{
    return self.playerLayer.isReadyForDisplay;
}

- (AVPlayer *)player
{
    return _player;
}


#pragma mark -
#pragma mark Setters

- (void)setPlayer:(AVPlayer*)player
{
    if (_player != player)
    {
        [_player pause];
        
        _player = player;
        
        AVPlayerLayer *newPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:_player];
        newPlayerLayer.frame        = self.frame;
        newPlayerLayer.videoGravity = self.videoFillMode;
        self.playerLayer            = newPlayerLayer;
    }
}

- (void)setPlayerLayer:(AVPlayerLayer *)playerLayer
{
    if (_playerLayer != playerLayer)
    {
        if (_playerLayer)
        {
            _playerLayer.player = nil;
            
            @try
            {
                [_playerLayer removeObserver:self
                                  forKeyPath:NSStringFromSelector(@selector(readyForDisplay))
                                     context:kMujiVideoPlayerViewContext];
            }
            @catch (NSException *__unused exception) {}
            
            [_playerLayer removeFromSuperlayer];
        }

        [self.layer insertSublayer:playerLayer atIndex:0];
        _playerLayer = playerLayer;
        
        [playerLayer addObserver:self
                      forKeyPath:NSStringFromSelector(@selector(readyForDisplay))
                         options:(NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew)
                         context:kMujiVideoPlayerViewContext];
    }
}


#pragma mark -
#pragma mark Initializers

- (id)init
{
    self = [super init];
    return self;
}

/*!
 Erik van der Neut, 3 February, 2015 --->
 Upon any resize after the player has already been loaded, make sure to also
 resize the video display to match the new size.
 This is needed for iPad support, for example.
 */
- (void)layoutSubviews
{
    [super layoutSubviews];
    self.playerLayer.frame = self.bounds;
    
//    ECDebugLog(@"VIDEO FRAMES :::> self.frame: %@, _playerLayer.frame: %@", NSStringFromCGRect(self.frame), NSStringFromCGRect(_playerLayer.frame));
}


- (void)setVideoFillMode:(NSString *)videoFillMode
{
    if (_videoFillMode != videoFillMode)
    {
        _videoFillMode                = [videoFillMode copy];
        self.playerLayer.videoGravity = _videoFillMode;
    }
}


#pragma mark -
#pragma mark NSObject

- (void)dealloc
{
    @try
    {
        [self.playerLayer removeObserver:self
                              forKeyPath:NSStringFromSelector(@selector(readyForDisplay))
                                 context:kMujiVideoPlayerViewContext];
    }
    @catch (NSException *exception) {}
    
    self.playerLayer.player = nil;
}


- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context
{
    if (context == kMujiVideoPlayerViewContext)
    {
        if ([keyPath isEqualToString:NSStringFromSelector(@selector(readyForDisplay))])
        {
            if ([self.delegate respondsToSelector:@selector(videoPlayerView:isReadyForVisualDisplay:)])
            {
                [self.delegate videoPlayerView:self isReadyForVisualDisplay:self.isReadyForVisualDisplay];
            }
        }
    }
    else
    {
         [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}


#pragma mark -
#pragma mark Public Methods

- (void)play
{
    [[self player] play];
    self.playing = YES;
}


- (void)pause
{
    [[self player] pause];
    self.playing = NO;
}


- (void)seekToTime:(CMTime)time
{
    [[self player] seekToTime:time];
}


- (void)seekToTime:(CMTime)time completion:(void (^)(void))completion
{
    [[self player] seekToTime:time completionHandler:^(BOOL finished)
     {
         completion();
     }];
    
    
    
}
- (void)seekToTime:(CMTime)time toleranceBefore:(CMTime)toleranceBefore toleranceAfter:(CMTime)toleranceAfter completionHandler:(void (^)(BOOL))completionHandler
{
    [[self player] seekToTime:time toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero completionHandler:^(BOOL finished) {
        
        completionHandler(finished);
    }];
}

@end
